   //$Id
#include "RtBase.h"
#include "dboci_adaptor.h"

/*--------------------------------------------------------------*/
/*                                                              */
/*      class CDBOciAdaptor                                     */
/*                                                              */
/*--------------------------------------------------------------*/
CDBOciAdaptor::CDBOciAdaptor(LPCSTR szDBSvr,
				LPCSTR szDBName,
				LPCSTR szUserName,
				LPCSTR szPasswd):m_pDatabase()
{
	m_pRecordset = new CRecordset_(&m_pDatabase);
	strcpy((char*)m_szDBSvr, szDBSvr);
	strcpy((char*)m_szDBName, szDBName);
	strcpy((char*)m_szUserName, szUserName);
	strcpy((char*)m_szPasswd, szPasswd);
	
	RT_INFO_TRACE("CDBOciAdaptor, "<<m_szDBSvr<<"| "<<m_szDBName<<"| "<<m_szUserName<<"| "<<m_szPasswd);
	m_bConnected = FALSE;

	m_nErrCode = 0;
}

CDBOciAdaptor::~CDBOciAdaptor()
{
	CloseDatabase();
	delete m_pRecordset;
}

RtResult CDBOciAdaptor::HandleException(CDBException_* e)
{
    RtResult dbret = TransErrRetValue(e->m_nRetCode,(const char*)e->m_szError);
	delete e;
	return dbret;
}

RtResult CDBOciAdaptor::OpenDatabase()
{
	try
	{
		m_pDatabase.Open((LPBYTE)m_szDBSvr, (LPBYTE)m_szDBName, 
				(LPBYTE)m_szUserName, (LPBYTE)m_szPasswd); 
		m_bConnected = TRUE;
	}
	catch(CDBException_* e)
	{
		return HandleException(e);
	}
	return RT_DB_SUCCESS;
}

RtResult CDBOciAdaptor::CloseDatabase()
{
	try
	{
		if(m_bConnected)
		{
			m_pDatabase.Close();
			m_bConnected = FALSE;
		}
	}
	catch(CDBException_* e)
	{
		return HandleException(e);
	}
	return RT_DB_SUCCESS;
}

RtResult CDBOciAdaptor::PutDataInDB(LPCSTR szSQLStmt, short sType)
{
	int nRet = RT_DB_SUCCESS;
	
	if (strlen(szSQLStmt) >= _MAX_SQLLENGTH)
	{
		RT_ERROR_TRACE("CDBOciAdaptor::PutDataInDB, szSQLStmt="<<szSQLStmt<<" len ="<<strlen(szSQLStmt));
		nRet = RT_DB_SQL_TOO_LONG;
		return nRet;
	}
	
	if(!m_bConnected)
		if((nRet = OpenDatabase()) != RT_DB_SUCCESS)
			return nRet;
		
	try
	{
#ifdef __ORACLE__
		m_pDatabase.ExecuteSQLDirect(szSQLStmt, NULL, sType);
#else
		m_pDatabase.ExecuteSQLDirect(szSQLStmt);
#endif
	}
	catch(CDBException_* e)
	{
		RT_WARNING_TRACE("CDBOciAdaptor::PutDataInDB, SQL = " << szSQLStmt);
		return HandleException(e);
	}
	return RT_DB_SUCCESS;
}

RtResult CDBOciAdaptor::GetDataFromDB(LPCSTR szSQLStmt, short sType)
{
	int nRet = RT_DB_SUCCESS;
	
	if (strlen((LPSTR)szSQLStmt) >= _MAX_SQLLENGTH)
	{
		nRet = RT_DB_SQL_TOO_LONG;
		return nRet;
	}
	
	if(!m_bConnected)
		if((nRet = OpenDatabase()) != RT_DB_SUCCESS)
			return nRet;
			
	try
	{
		m_pRecordset->Destroy();
#ifdef __ORACLE__
		m_pDatabase.ExecuteSQLDirect(szSQLStmt, m_pRecordset, sType);
#else
		BOOL bRemote = FALSE;
		if(sType != 0)
			bRemote = TRUE;
		m_pDatabase.ExecuteSQLDirect(szSQLStmt, m_pRecordset, bRemote);
#endif
	
	}
	catch(CDBException_* e)
	{
		RT_WARNING_TRACE("CDBOciAdaptor::GetDataFromDB, SQL = " << szSQLStmt);
		return HandleException(e);
	}
	return RT_DB_SUCCESS;
}

#ifdef __ORACLE__
RtResult CDBOciAdaptor::GetIntFromOCINumber(OCINumber* pnumber, DWORD &dwVal)
{
	if(!m_bConnected)
	{
		int nRet;
		if((nRet = OpenDatabase()) != RT_DB_SUCCESS)
			return nRet;
	}

	try
	{
		m_pDatabase.GetIntFromOCINumber(pnumber, (LPBYTE)&dwVal);
	}
	catch(CDBException_* e)
	{
		return HandleException(e);
	}
	return RT_DB_SUCCESS;
	
}

RtResult CDBOciAdaptor::GetIntFromOCINumber(OCINumber* pnumber, WORD &wVal)
{
	if(!m_bConnected)
	{
		int nRet;
		if((nRet = OpenDatabase()) != RT_DB_SUCCESS)
			return nRet;
	}

	try
	{
		DWORD dwVal;
		m_pDatabase.GetIntFromOCINumber(pnumber, (LPBYTE)&dwVal);
		wVal = dwVal;
	}
	catch(CDBException_* e)
	{
		return HandleException(e);
	}
	return RT_DB_SUCCESS;
	
}

RtResult CDBOciAdaptor::GetUIntFromOCINumber(OCINumber* pnumber, DWORD &dwVal)
{
	if(!m_bConnected)
	{
		int nRet;
		if((nRet = OpenDatabase()) != RT_DB_SUCCESS)
			return nRet;
	}

	try
	{
		m_pDatabase.GetUIntFromOCINumber(pnumber, (LPBYTE)&dwVal);
	}
	catch(CDBException_* e)
	{
		return HandleException(e);
	}
	return RT_DB_SUCCESS;
	
}

RtResult CDBOciAdaptor::GetRealFromOCINumber(OCINumber* pnumber, double &fVal)
{
	if(!m_bConnected)
	{
		int nRet;
		if((nRet = OpenDatabase()) != RT_DB_SUCCESS)
			return nRet;
	}

	try
	{
		m_pDatabase.GetRealFromOCINumber(pnumber, (LPBYTE)&fVal);
	}
	catch(CDBException_* e)
	{
		return HandleException(e);
	}
	return RT_DB_SUCCESS;
}

RtResult CDBOciAdaptor::GetGMTTimeFromOCIDate(OCIDate*  ptime, gmt_time*  tm)
{
	if(!m_bConnected)
	{
		int nRet;
		if((nRet = OpenDatabase()) != RT_DB_SUCCESS)
			return nRet;
	}

	try
	{
		m_pDatabase.GetGMTTimeFromOCIDate(ptime, tm);
	}
	catch(CDBException_* e)
	{
		return HandleException(e);
	}
	return RT_DB_SUCCESS;
}

RtResult CDBOciAdaptor::TransErrRetValue(int nRetCode, const char* strErr)
{
//	RT_INFO_TRACE("CDBOciAdaptor::TransErrRetValue, nRetCode=" << nRetCode);
	int nDBHandlerRetValue = RT_DB_OTHER_ERR;
	BOOL bReconnect = FALSE;
	switch(nRetCode)
	{
	case 900 : /* ORA-00900: invalid SQL statement */
		nDBHandlerRetValue = RT_DB_INVALID_SQL_STMT;
		break;	
	case 1017 : /* ORA-01017: invalid username/password; logon denied */
		nDBHandlerRetValue = RT_DB_WRONG_USER_OR_PASSWD;
		break;	
	case 3113://"end-of-file on communication channel"
	case 3114://"not connected to ORACLE"
	case 1034 : /* ORA-01034: ORACLE not available */
	case 1033:/*ORACLE initialization or shutdown in progress*/
	case 1089:/*immediate shutdown in progress - no operations are permitted*/
		nDBHandlerRetValue = RT_DB_IS_DOWN;
		bReconnect = TRUE;
		break;
	case 12154 : /* ORA-12154: TNS:could not resolve service name */
		nDBHandlerRetValue = RT_DB_WRONG_DB;
		bReconnect = TRUE;
		break;
	case 12541 : /* ORA-12541: TNS:no listener */
		nDBHandlerRetValue = RT_DB_NO_LISTENER;
		bReconnect = TRUE;
		break;	
	case _OCI_OCINUMBER_IS_INTEGER : /* The input OCINumber is a Integer not a float. */
		nDBHandlerRetValue = RT_DB_OCINUMBER_IS_INTEGER;
		break;	
	default : 
		//RT_ERROR_TRACE("CDBOciAdaptor::TransErrRetValue, ErrCode=" << nRetCode);	
		nDBHandlerRetValue = RT_DB_OTHER_ERR;
		break;	
	}
	
	if(bReconnect)
	{
		//RT_ERROR_TRACE("CDBOciAdaptor::TransErrRetValue, DB should be re-open");	
		CloseDatabase();
	}

	m_nErrCode = nRetCode;

	return nDBHandlerRetValue;
}
#else

RtResult CDBOciAdaptor::InsertAutoIncRow(LPCSTR szSQLStmt, LONGLONG& ulAutoIncNumber)
{
	int nRet = RT_DB_SUCCESS;
	
	if (strlen(szSQLStmt) >= _MAX_SQLLENGTH)
	{
		RT_ERROR_TRACE("CDBOciAdaptor::InsertAutoIncRow, szSQLStmt="<<szSQLStmt<<" len ="<<strlen(szSQLStmt));
		nRet = RT_DB_SQL_TOO_LONG;
		return nRet;
	}
	
	if(!m_bConnected)
		if((nRet = OpenDatabase()) != RT_DB_SUCCESS)
			return nRet;
		
	try
	{
		m_pDatabase.InsertAutoIncRow(szSQLStmt, ulAutoIncNumber);
	}
	catch(CDBException_* e)
	{
		RT_WARNING_TRACE("CDBOciAdaptor::InsertAutoIncRow, SQL = " << szSQLStmt);
		return HandleException(e);
	}
	return RT_DB_SUCCESS;
}

RtResult CDBOciAdaptor::TransErrRetValue(int nRetCode, const char* strErr)
{
	RT_ERROR_TRACE("CDBOciAdaptor::TransErrRetValue, ErrCode=" << nRetCode<<", reason:"<<strErr);
	BOOL bReconnect = FALSE;
	switch(nRetCode)
	{
	case 2003://can't connect to server.
	case 2006:// CR_SERVER_GONE_ERROR
		bReconnect = TRUE;
		break;
	case 1064:
		return RT_DB_INVALID_SQL_STMT;

	default:
		break;
	}
	if(bReconnect)
		CloseDatabase();

	return RT_DB_OTHER_ERR;
}
#endif

int CDBOciAdaptor::GetErrCode()
{
	return m_nErrCode;
}
////////////////////////////////Add for Statment Binding//////////////////////////
#ifdef __ORACLE__
RtResult CDBOciAdaptor::PrepareStmt(LPCSTR pszSQLStmt)
{
	int nRet;

	if(!m_bConnected)
		if((nRet = OpenDatabase()) != RT_DB_SUCCESS)
			return nRet;

	try
	{
		nRet = m_pDatabase.PrepareSQLStmt(pszSQLStmt);
	}
	catch(CDBException_* e)
	{
		RT_WARNING_TRACE("CDBOciAdaptor::PrepareStmt, e.m_nRetCode = " << e->m_nRetCode << "SQL=" << pszSQLStmt);
		return HandleException(e);
	}
	if(nRet < 0)
	{
		RT_INFO_TRACE("CDBOciAdaptor::PrepareStmt, nRet=" << nRet << ",sql =" << pszSQLStmt);
		return nRet;
	}
	
	return RT_DB_SUCCESS;
}

RtResult CDBOciAdaptor::BindStmtInParam(LPCSTR pszParamName, DWORD &dwContent)
{
	int nRet;

	if(!m_bConnected)
			return RT_ERROR_NOT_AVAILABLE;

	try
	{
		nRet = m_pDatabase.BindInParamByName(pszParamName, dwContent);
	}
	catch(CDBException_* e)
	{
		RT_WARNING_TRACE("CDBOciAdaptor::BindStmtParam, e->m_nRetCode = " << e->m_nRetCode);
		return HandleException(e);
	}
	if(nRet < 0)
	{
		RT_INFO_TRACE("CDBOciAdaptor::BindStmtParam, nRet=" << nRet);
		return nRet;
	}
	return RT_DB_SUCCESS;
	
}

RtResult CDBOciAdaptor::BindStmtInParam(LPCSTR pszParamName, LPBYTE pszContent)
{
	int nRet;

	if(!m_bConnected)
			return RT_ERROR_NOT_AVAILABLE;

	try
	{
		nRet = m_pDatabase.BindInParamByName(pszParamName, pszContent);
	}
	catch(CDBException_* e)
	{
		RT_WARNING_TRACE("CDBOciAdaptor::BindStmtParam, e.m_nRetCode = " << e->m_nRetCode);
		return HandleException(e);
	}
	if(nRet < 0)
	{
		RT_INFO_TRACE("CDBOciAdaptor::BindStmtParam, nRet=" << nRet);
		return nRet;
	}
	return RT_DB_SUCCESS;
	
}

RtResult CDBOciAdaptor::ExecutePreparedSQLStmt()
{
	int nRet;

	if(!m_bConnected)
			return RT_ERROR_NOT_AVAILABLE;
		
	try
	{
		nRet = m_pDatabase.ExecutePreparedSQLStmt();
	}
	catch(CDBException_* e)
	{
		RT_WARNING_TRACE("CDBOciAdaptor::ExecutePreparedSQLStmt, e.m_nRetCode = " << e->m_nRetCode);		
		return HandleException(e);
	}
	if(nRet < 0)
	{
		RT_INFO_TRACE("CDBOciAdaptor::ExecutePreparedSQLStmt, nRet=" << nRet);
		return nRet;
	}
	return RT_DB_SUCCESS;
}

RtResult CDBOciAdaptor::BindStmtOutParam(LPCSTR pszParamName, DWORD &dwContent)
{
	int nRet;

	if(!m_bConnected)
			return RT_ERROR_NOT_AVAILABLE;

	try
	{
		nRet = m_pDatabase.BindOutParamByName(pszParamName, dwContent);
	}
	catch(CDBException_* e)
	{
		RT_WARNING_TRACE("CDBOciAdaptor::BindStmtOutParam, e.m_nRetCode = " << e->m_nRetCode);
		return HandleException(e);
	}
	if(nRet < 0)
	{
		RT_INFO_TRACE("CDBOciAdaptor::BindStmtOutParam, nRet=" << nRet);
		return nRet;
	}
	return RT_DB_SUCCESS;
	
}

RtResult CDBOciAdaptor::BindStmtOutParam(LPCSTR pszParamName, LPBYTE pszContent)
{
	int nRet;

	if(!m_bConnected)
			return RT_ERROR_NOT_AVAILABLE;

	try
	{
		nRet = m_pDatabase.BindOutParamByName(pszParamName, pszContent);
	}
	catch(CDBException_* e)
	{
		RT_WARNING_TRACE("CDBOciAdaptor::BindStmtOutParam, e.m_nRetCode = " << e->m_nRetCode);
		return HandleException(e);
	}
	if(nRet < 0)
	{
		RT_INFO_TRACE("CDBOciAdaptor::BindStmtOutParam, nRet=" << nRet);
		return nRet;
	}
	return RT_DB_SUCCESS;
	
}
#endif


